import math
import numpy as np
import scipy
import scipy.signal
import scipy.stats


def process_AE_data(data: np.ndarray, threshold: int, fs: int) -> tuple:
    """
    提取声发射数据的特征

    :param data: 声发射数据
    :param threshold: 门限电压值
    :param fs: 采样频率
    :return: 提取的特征值 \n
            max_amp, 幅度 \n
            asl, 平均信号电平 \n
            rms, 有效值电压 \n
            count, 超过门限的次数 \n
            arrive_time, 声发射事件到达时间 \n
            duration, 声发射事件持续时间 \n
            rise_time 声发射事件上升时间
    """
    n = len(data)
    amplitude = 20 * np.log10(data * 1000. / 1.)  # 转换为dB
    max_amp = abs(amplitude).max()  # 最大幅值
    # peaks, _ = scipy.signal.find_peaks(amplitude, height=threshold)  # 寻找峰值

    count = 0  # 计数
    asl = data.mean()  # 平均信号电平
    rms = math.sqrt(sum([x ** 2 for x in data]) / len(data))  # 有效值电压

    ffted = abs(np.fft.fft(data))[:n//2]
    freq = fs / n * np.arange(n // 2)
    domain_freq = freq[np.argmax(ffted)]

    # 计算能量
    dt = 1 / fs * 1e6
    temp = np.insert(data, 0, 0)
    energy = [(temp[i]**2 + temp[i+1]**2) * dt / 2 for i in range(n)]

    # arrive_time = []
    # duration = []
    # rise_time = []
    # flash = []
    # start_time = None
    # wave_flag = False
    # peak_flag = False
    # tollerance = 120
    # # 遍历数据，找到超过阈值的点
    # for idx in range(n):

    #     if abs(energy[idx]) > threshold and not start_time:
    #         # 疑似进入声发射事件
    #         wave_flag = True if energy[idx] < -threshold else False
    #         peak_flag = True if energy[idx] > threshold else False
    #         start_time = idx * ((1 / fs) * 1e6)
    #         flash.append([idx * ((1 / fs) * 1e6), energy[idx]])
    #     elif tollerance > 0:
    #         # 如果当前处在一个声发射事件中，那就寻找结束的时间和峰值对应的时间
    #         if abs(energy[idx]) > threshold:
    #             wave_flag = True if abs(energy[idx] < -threshold) else False
    #             peak_flag = True if energy[idx] > threshold else False
    #             # end_time = idx * ((1 / fs) * 1e6)
    #             flash.append([idx * ((1 / fs) * 1e6), energy[idx]])
    #         else:
    #             tollerance -= (1 / fs) * 1e6
    #     elif tollerance <=0 or idx == len(amplitude) - 1:
    #         # 一个声发射事件已经结束，重置
    #         start_time = None
    #         tollerance = 120
    #         # 根据波谷标志位判断是否要计算刚结束的声发射事件的持续时间，上升时间
    #         if wave_flag & peak_flag:
    #             count += 1
    #             # duration.append(end_time - start_time)
    #             flash.sort(key=lambda x: x[1], reverse=True) # 降序排列
    #             duration.append(flash[0][0] - flash[-1][0])
    #             # rise_time.append(flash[0][0] - start_time)
    #         flash.clear()


    # arrive_time = []
    # duration = []
    # rise_time = []
    # flash = []
    # start_time = None
    # tollerance = 120
    # # 遍历数据，找到超过阈值的点
    # for idx, item in enumerate(amplitude):

    #     if not start_time and item > threshold:
    #         # 到达时间
    #         count += 1
    #         start_time = end_time = idx * ((1 / fs) * 1e6)
    #         arrive_time.append(start_time)
    #         flash.append([idx * ((1 / fs) * 1e6), item])
    #     elif tollerance > 0:
    #         # 如果当前处在一个声发射事件中，那就寻找结束的时间和峰值对应的时间
    #         if item > threshold:
    #             count += 1
    #             end_time = idx * ((1 / fs) * 1e6)
    #             flash.append(item)
    #         else:
    #             tollerance -= (1 / fs) * 1e6
    #     elif tollerance <=0 or idx == len(amplitude) - 1:
    #         # 一个声发射事件已经结束，重置
    #         start_time = None
    #         tollerance = 120
    #         # 计算刚结束的声发射事件的持续时间，上升时间
    #         duration.append(end_time - start_time)
    #         flash.sort(key=lambda x: x[1], reverse=True) # 降序排列
    #         rise_time.append(flash[0][0] - start_time)
    #         flash.clear()
    # return max_amp, asl, rms, count, arrive_time, duration, rise_time, domain_freq
    return max_amp, asl, rms, count, domain_freq


if __name__  == "__main__":
    test = np.random.random(1000) * 100
    process_AE_data(test, 5, 10000)